/*
 * Copyright (c) www.bugull.com
 */

package com.bugull.farm.core.handler;

import com.bugull.farm.core.frame.exception.BuguException;
import com.bugull.farm.core.frame.structure.Frame;
import com.bugull.farm.core.utils.BufUtil;
import com.bugull.farm.core.utils.ByteUtil;
import com.bugull.farm.core.utils.IpUtil;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

import org.apache.logging.log4j.*;

/**
 * Handler for App, it checks company code and auth code.
 * 
 * As the last handler, it handle the exception.
 * 
 * @author Frank Wen(xbwen@hotmail.com)
 */
public abstract class AbstractAppFrameHandler extends SimpleChannelInboundHandler<Frame> {
    
    protected final static Logger logger = LogManager.getLogger(AbstractAppFrameHandler.class);

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Frame msg) {
    	try{
	        processFrame(ctx, msg);
    	}catch(Exception e){
    		e.printStackTrace();
    		logger.error("AbstractAppFrameHandler can't handle the message: "+msg.getHexRequest(),e);
    	}
        
    }
    
    protected abstract void processFrame(ChannelHandlerContext ctx, Frame frame) throws Exception;
    
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
    	cause.printStackTrace();
		logger.error("Channel closed beacuse an exception caught : " + cause);
		Channel ch = ctx.channel();
		if (cause instanceof BuguException) {
			BuguException e = (BuguException) cause;
			if (ch.isActive()) {
				ctx.writeAndFlush(e.getErrorResponse()).addListener(ChannelFutureListener.CLOSE);			
			}
		} else {
			if (ch.isActive()) {
	            ch.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
	        }
		}
    }

}
